package com.pamakids.utils;

import android.content.Context;
import android.location.Location;
import android.location.LocationManager;
import android.os.Build;
import android.os.Environment;
import android.os.StatFs;
import android.telephony.TelephonyManager;
import com.adobe.fre.*;

import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.util.HashMap;
import java.util.Map;

public class DeviceDescriptionContext extends FREContext{

    /**
     * 获取设备型号
     */
    public static final String KEY_MODEL = "getDeviceModel";
    /**
     * 获取os版本号
     */
    public static final String KEY_OS_VERSION = "getOSVersion";
    /**
     * 获取电话状态：
     * 1. 无活动
     * 2. 响铃
     * 3. 摘机
     */
    public static final String KEY_CALL_STATE = "getCallState";
    /**
     * 电话方位
     */
    public static final String KEY_CELL_LOCATION = "getCellLocation";
    /**
     * 设备ID
     * GSM手机的IMEI 和 CDMA手机的MEID
     * Return null if device ID is not available。
     */
    public static final String KEY_DEVICE_ID = "getDeviceId";
    /**
     * 设备的软件版本号
     * 例如：the IMEI/SV(software version) for GSM phones.
     * Retrun null if the software version isnot available.
     */
    public static final String KEY_SOFTWARE_VERSION = "getSoftWareVersion";
    /**
     * 手机号
     * GSM手机的 MSISDN。
     * Retrun null if it's unavailable.
     */
    public static final String KEY_PHONE_NUMBER = "getPhoneNumber";
    /**
     * 获取手机类型，如
     * PHONE_TYPE_NONE	无信号
     * PHONE_TYPE_GSM	GSM信号
     * PHONE_TYPE_CDMA	CDMA信号
     */
    public static final String KEY_PHONE_TYPE = "getPhoneType";
    /**
     * 获取ISO国家码，相当于提供sim卡的国家码
     */
    public static final String KEY_SIM_COUNTRY_ISO = "getSimCountryIso";
    /**
     * 服务商名称
     * 例如：中国移动、联通
     * SIM卡的状态必须是SIM_STATE_READY
     */
    public static final String KEY_SIM_OPERATOR_NAME = "getSimOperatorName";
    /**
     * sim卡的序列号，需要权限：READ_PHONE_STATE
     */
    public static final String KEY_SIM_SERIAL_NUMBER = "getSimSerialNumber";
    /**
     * 判断ICC卡是否存在
     */
    public static final String KEY_HAS_ICC_CARD = "hasIccCard";
    /**
     * 获取CPU序列号(16位)
     * 读取失败则为'0000000000000000'
     */
    public static final String KEY_CPU_SERIAL_NUMBER = "getCPUSerial";
    /**
     * 通过GPS获取地理位置信息
     */
    public static final String KEY_LOCATION_GPS = "getLocationByGPS";
    /**
     * 通过NETWORK获取地理位置信息
     */
    public static final String KEY_LOCATION_NETWORD = "getLocationByNetwork";
    /**
     * 获取SD卡信息
     */
    public static final String KEY_SDCARD_INFO = "getSDCardInfo";


    @Override
    public Map<String, FREFunction> getFunctions() {
        Map<String, FREFunction> map = new HashMap<String, FREFunction>();
        map.put("getDeviceInfo", new GetDeviceInfoFunction());
        return map;
    }

    @Override
    public void dispose() {
    }

    String getCPUSerial(){
        String str, cpuAddress="0000000000000000";
        try {
            //读取CPU信息
            Process pp = Runtime.getRuntime().exec("cat /proc/cpuinfo");
            InputStreamReader ir = new InputStreamReader(pp.getInputStream());
            LineNumberReader input = new LineNumberReader(ir);
            //查找CPU序列号
            for(int i = 0; i<100; i++){
                str = input.readLine();
                if(str != null){
                    if (str.contains("Serial")){
                        String strCPU = str.substring(str.indexOf(":")+1, str.length());
                        cpuAddress = strCPU.trim();
                        break;
                    }
                } else {
                    break;
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        return cpuAddress;
    }

    FREObject getInfoByKey(String key) throws FREWrongThreadException {
        FREObject freObject = null;
        if (key.equals(KEY_MODEL) || key.equals(KEY_OS_VERSION))
            freObject = FREObject.newObject(key.equals(KEY_OS_VERSION) ? Build.VERSION.RELEASE : Build.MODEL);
        else if (key.equals(KEY_CPU_SERIAL_NUMBER))
            freObject = FREObject.newObject(getCPUSerial());
        else if (key.equals(KEY_LOCATION_GPS) || key.equals(KEY_LOCATION_NETWORD)){
            LocationManager locationManager =
                    (LocationManager) this.getActivity().getSystemService(Context.LOCATION_SERVICE);
            String provider = key.equals(KEY_LOCATION_NETWORD) ?
                    LocationManager.NETWORK_PROVIDER : LocationManager.GPS_PROVIDER;
            Location location = locationManager.getLastKnownLocation(provider);
            double lat = location.getLatitude();
            double lng = location.getLongitude();
            freObject = FREObject.newObject(String.valueOf(lat) + "," + String.valueOf(lng));
        }else if(key.equals(KEY_SDCARD_INFO)){
            try {
                freObject = FREObject.newObject("Object", null);
                boolean b = Environment.getExternalStorageState().equals(Environment.MEDIA_MOUNTED);
                freObject.setProperty("hasSDCard", FREObject.newObject(b));
                if (b){
                    File path = Environment.getExternalStorageDirectory();
                    StatFs statFs = new StatFs(path.getPath());
                    long blocksize = statFs.getBlockSize();
                    long freeblock = statFs.getAvailableBlocks();
                    long totalblock = statFs.getBlockCount();
                    freObject.setProperty("freeSize", FREObject.newObject(blocksize*freeblock));
                    freObject.setProperty("totalSize", FREObject.newObject(blocksize*totalblock));
                }
            } catch (FRETypeMismatchException e) {
                e.printStackTrace();
            } catch (FREInvalidObjectException e) {
                e.printStackTrace();
            } catch (FREASErrorException e) {
                e.printStackTrace();
            } catch (FRENoSuchNameException e) {
                e.printStackTrace();
            } catch (FREReadOnlyException e) {
                e.printStackTrace();
            }
        } else {
            TelephonyManager telephonyManager =
                    (TelephonyManager) this.getActivity().getSystemService(Context.TELEPHONY_SERVICE);
            if (key.equals(KEY_CALL_STATE))
                freObject = FREObject.newObject(String.valueOf(telephonyManager.getCallState()));
            else if (key.equals(KEY_CELL_LOCATION))
                freObject = FREObject.newObject(telephonyManager.getCellLocation().toString());
            else if(key.equals(KEY_DEVICE_ID))
                freObject = FREObject.newObject(telephonyManager.getDeviceId());
            else if (key.equals(KEY_HAS_ICC_CARD))
                freObject = FREObject.newObject(telephonyManager.hasIccCard());
            else if (key.equals(KEY_PHONE_NUMBER))
                freObject = FREObject.newObject(telephonyManager.getLine1Number());
            else if (key.equals(KEY_PHONE_TYPE))
                freObject = FREObject.newObject(telephonyManager.getPhoneType());
            else if (key.equals(KEY_SIM_COUNTRY_ISO))
                freObject = FREObject.newObject(telephonyManager.getSimCountryIso());
            else if (key.equals(KEY_SIM_SERIAL_NUMBER))
                freObject = FREObject.newObject(telephonyManager.getSimSerialNumber());
            else if (key.equals(KEY_SOFTWARE_VERSION))
                freObject = FREObject.newObject(telephonyManager.getDeviceSoftwareVersion());
            else if (key.equals(KEY_SIM_OPERATOR_NAME))
                freObject = FREObject.newObject(telephonyManager.getSimOperatorName());
        }
        return freObject;
    }
}

class GetDeviceInfoFunction implements FREFunction{

    @Override
    public FREObject call(FREContext freContext, FREObject[] freObjects) {

        DeviceDescriptionContext context = (DeviceDescriptionContext) freContext;
        try {
            String key = freObjects[0].getAsString();
            return context.getInfoByKey(key);
        } catch (FRETypeMismatchException e) {
            e.printStackTrace();
        } catch (FREInvalidObjectException e) {
            e.printStackTrace();
        } catch (FREWrongThreadException e) {
            e.printStackTrace();
        }
        return null;
    }
}
